package com.pony.iphone.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pony.iphone.dto.QWenResponse;
import com.pony.iphone.dto.QuestionAnswerDto;
import com.pony.iphone.dto.UsageStats;
import com.theokanning.openai.completion.chat.*;
import com.theokanning.openai.service.OpenAiService;
import com.pony.iphone.exception.QWenServiceException;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

@Slf4j
@Service
public class QWenChatService {

    private final OpenAiService openAiService;
    private final QWenHistoryService historyService;
    private final AtomicLong usedTokens = new AtomicLong(0);

    private static final String MODEL_NAME = "deepseek-chat";

    @Value("${app.qwen.free-tier.total-tokens:1000000}")
    private Long FREE_TIER_LIMIT;

    @Value("${spring.ai.openai.api-key}")
    private String apiKey;

    @Value("${qwen.api.max-tokens:2000}")
    private Integer maxTokens;

    @Value("${qwen.api.temperature:0.7}")
    private Double temperature;

    // 调用方式开关：true使用直接HTTP调用，false使用OpenAiService
    private boolean useDirectCall = true;

    // 只保留一个构造函数，使用依赖注入
    public QWenChatService(OpenAiService openAiService, QWenHistoryService historyService) {
        this.openAiService = openAiService;
        this.historyService = historyService;

        // 初始化历史记录目录
        this.historyService.initHistoryDirectory();
        log.info("✅ QWenChatService初始化完成，默认使用直接HTTP调用");
    }

    /**
     * 构建系统提示词
     */
    private String buildSystemPrompt(QuestionAnswerDto request) {
        String answerOptions = String.join("、", request.getAnswerList());

        return String.format("""
            你是一个智能问答助手。请根据用户的问题，从以下候选答案中选择最合适的一个：
            候选答案：%s
            
            要求：
            1. 必须从候选答案中选择，不能自己创造答案
            2. 只返回选择的答案内容，不要额外解释
            3. 如果问题与候选答案不匹配，选择最接近的答案
            4. 回答要简洁，直接输出答案
            """, answerOptions);
    }

    /**
     * 构建用户消息
     */
    private String buildUserMessage(QuestionAnswerDto request) {
        return request.getQuestion();
    }

    /**
     * 方法2: 使用HTTP客户端直接调用（实际使用的方法）
     */
    private String callDeepSeekDirectly(String systemPrompt, String userMessage) {
        int maxRetries = 3;
        int retryCount = 0;
        long retryDelay = 5000; // 5秒

        while (retryCount <= maxRetries) {
            try {
                String apiUrl = "https://api.deepseek.com/v1/chat/completions";

                // 构建请求体
                Map<String, Object> requestBody = new HashMap<>();
                requestBody.put("model", "deepseek-chat");
                requestBody.put("stream", false);

                List<Map<String, String>> messages = new ArrayList<>();
                if (systemPrompt != null && !systemPrompt.trim().isEmpty()) {
                    messages.add(Map.of("role", "system", "content", systemPrompt));
                }
                messages.add(Map.of("role", "user", "content", userMessage));
                requestBody.put("messages", messages);

                requestBody.put("max_tokens", maxTokens);
                requestBody.put("temperature", temperature);

                // 创建HTTP客户端 - 使用更长的超时时间
                OkHttpClient client = new OkHttpClient.Builder()
                        .connectTimeout(10, TimeUnit.MINUTES)
                        .readTimeout(10, TimeUnit.MINUTES)
                        .writeTimeout(10, TimeUnit.MINUTES)
                        .build();

                // 构建请求
                ObjectMapper objectMapper = new ObjectMapper();
                RequestBody body = RequestBody.create(
                        objectMapper.writeValueAsString(requestBody),
                        MediaType.parse("application/json")
                );

                Request request = new Request.Builder()
                        .url(apiUrl)
                        .post(body)
                        .addHeader("Authorization", "Bearer " + apiKey)
                        .addHeader("Content-Type", "application/json")
                        .addHeader("User-Agent", "MyApp/1.0")
                        .build();

                log.info("🔄 第{}次直接调用DeepSeek API...", retryCount + 1);
                long startTime = System.currentTimeMillis();

                // 执行请求
                try (Response response = client.newCall(request).execute()) {
                    long endTime = System.currentTimeMillis();
                    log.info("📡 API响应时间: {}ms", (endTime - startTime));

                    if (response.isSuccessful()) {
                        String responseBody = response.body().string();
                        log.debug("API响应: {}", responseBody);

                        JsonNode jsonNode = objectMapper.readTree(responseBody);
                        String content = jsonNode.path("choices").get(0).path("message").path("content").asText();
                        log.info("✅ 直接调用成功，获取到答案");
                        return content;
                    } else {
                        String errorBody = response.body().string();
                        log.error("❌ API调用失败: HTTP {} - {}", response.code(), errorBody);

                        // 如果是认证错误，直接抛出，不需要重试
                        if (response.code() == 401) {
                            throw new QWenServiceException("API认证失败，请检查API密钥: " + errorBody);
                        }

                        // 其他错误继续重试
                        throw new RuntimeException("HTTP " + response.code() + ": " + errorBody);
                    }
                }

            } catch (Exception e) {
                retryCount++;
                log.warn("❌ 第{}次直接调用失败: {}", retryCount, e.getMessage());

                if (retryCount > maxRetries) {
                    log.error("🔥 所有重试次数已用完");
                    throw new QWenServiceException("直接调用DeepSeek API失败，重试" + maxRetries + "次后仍然失败: " + e.getMessage(), e);
                }

                // 等待后重试
                try {
                    log.info("⏳ 等待{}ms后重试...", retryDelay);
                    Thread.sleep(retryDelay);
                    retryDelay *= 2; // 指数退避
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    throw new QWenServiceException("重试被中断", ie);
                }
            }
        }

        throw new QWenServiceException("直接调用DeepSeek API失败");
    }

    /**
     * 原有的OpenAiService调用方法（作为备选）
     */
    private String callQWenAPI(String systemPrompt, String userMessage) {
        int maxRetries = 3;
        int retryCount = 0;
        long retryDelay = 5000; // 5秒

        while (retryCount <= maxRetries) {
            try {
                List<ChatMessage> messages = new ArrayList<>();

                if (systemPrompt != null && !systemPrompt.trim().isEmpty()) {
                    messages.add(new ChatMessage(ChatMessageRole.SYSTEM.value(), systemPrompt));
                }

                messages.add(new ChatMessage(ChatMessageRole.USER.value(), userMessage));

                ChatCompletionRequest request = ChatCompletionRequest.builder()
                        .model(MODEL_NAME)
                        .messages(messages)
                        .maxTokens(maxTokens)
                        .temperature(temperature)
                        .build();

                log.info("🔄 第{}次调用OpenAiService", retryCount + 1);
                ChatCompletionResult result = openAiService.createChatCompletion(request);
                String response = result.getChoices().get(0).getMessage().getContent();
                log.info("✅ OpenAiService调用成功");
                return response;

            } catch (Exception e) {
                retryCount++;
                log.warn("❌ 第{}次OpenAiService调用失败: {}", retryCount, e.getMessage());

                if (retryCount > maxRetries) {
                    throw new QWenServiceException("OpenAiService调用失败，重试" + maxRetries + "次后仍然失败: " + e.getMessage(), e);
                }

                try {
                    Thread.sleep(retryDelay);
                    retryDelay *= 2;
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    throw new QWenServiceException("重试被中断", ie);
                }
            }
        }
        throw new QWenServiceException("OpenAiService调用失败");
    }

    /**
     * 处理AI的回答，确保返回的是候选答案中的一个
     */
    private String processAIAnswer(String aiAnswer, List<String> answerList) {
        if (aiAnswer == null || aiAnswer.trim().isEmpty()) {
            return getRandomAnswer(answerList);
        }

        // 清理AI回答中的空格和标点
        String cleanedAnswer = aiAnswer.trim()
                .replace("。", "")
                .replace("，", "")
                .replace(".", "")
                .replace(",", "")
                .replace("!", "")
                .replace("？", "")
                .replace("?", "");

        // 检查是否直接匹配候选答案
        for (String candidate : answerList) {
            if (cleanedAnswer.equalsIgnoreCase(candidate.trim())) {
                return candidate;
            }
        }

        // 检查是否包含候选答案
        for (String candidate : answerList) {
            if (cleanedAnswer.toLowerCase().contains(candidate.toLowerCase())) {
                return candidate;
            }
        }

        // 如果没有匹配，使用随机答案
        log.warn("AI回答 '{}' 未匹配到候选答案，使用随机答案", aiAnswer);
        return getRandomAnswer(answerList);
    }

    /**
     * 从答案列表中随机选择一个答案
     */
    private String getRandomAnswer(List<String> answerList) {
        if (answerList == null || answerList.isEmpty()) {
            return "Unknown";
        }
        return answerList.get(new Random().nextInt(answerList.size()));
    }

    /**
     * 聊天方法（集成历史记录）- 主要方法
     */
    public QWenResponse chatWithHistory(QuestionAnswerDto request) {
        log.info("千问API请求: {}", request.getQuestion());

        try {
            // 构建系统提示词
            String systemPrompt = buildSystemPrompt(request);
            String userMessage = buildUserMessage(request);

            // 调用千问API - 根据开关选择调用方式
            long startTime = System.currentTimeMillis();
            String aiAnswer;

            if (useDirectCall) {
                log.info("🚀 使用直接HTTP调用DeepSeek API");
                aiAnswer = callDeepSeekDirectly(systemPrompt, userMessage);
            } else {
                log.info("🚀 使用OpenAiService调用DeepSeek API");
                aiAnswer = callQWenAPI(systemPrompt, userMessage);
            }

            long responseTime = System.currentTimeMillis() - startTime;

            // 处理AI的回答
            String finalAnswer = processAIAnswer(aiAnswer, request.getAnswerList());

            // 记录问答历史
            historyService.recordQAHistory(request, aiAnswer, finalAnswer);

            // 更新token使用量（直接调用无法准确获取，使用估算值）
            long estimatedTokens = aiAnswer.length() / 4; // 粗略估算
            usedTokens.addAndGet(estimatedTokens);

            return QWenResponse.builder()
                    .answer(finalAnswer)
                    .totalTokensUsed(usedTokens.get())
                    .responseTime(responseTime)
                    .remainingTokens(FREE_TIER_LIMIT - usedTokens.get())
                    .status("SUCCESS")
                    .model("deepseek-chat")
                    .build();

        } catch (QWenServiceException e) {
            log.error("千问服务异常: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("系统异常: {}", e.getMessage(), e);
            throw new QWenServiceException("千问服务暂时不可用: " + e.getMessage(), e);
        }
    }

    /**
     * 基础聊天功能（兼容旧版本）
     */
    public QWenResponse chat(String message) {
        // 创建一个简单的QuestionAnswerDto来兼容旧调用
        QuestionAnswerDto dummyRequest = new QuestionAnswerDto();
        dummyRequest.setQuestion(message);
        dummyRequest.setAnswerList(List.of("是", "否")); // 默认答案
        dummyRequest.setLibraryName("default");

        return chatWithHistory(dummyRequest);
    }

    /**
     * 切换调用方式
     */
    public void switchToDirectCall(boolean useDirect) {
        this.useDirectCall = useDirect;
        log.info("🔄 切换调用方式: {}", useDirect ? "直接HTTP调用" : "OpenAiService调用");
    }

    /**
     * 获取当前调用方式信息
     */
    public Map<String, Object> getCallMethodInfo() {
        Map<String, Object> info = new HashMap<>();
        info.put("当前调用方式", useDirectCall ? "直接HTTP调用" : "OpenAiService调用");
        info.put("API密钥长度", apiKey.length());
        info.put("API密钥前缀", apiKey.substring(0, Math.min(8, apiKey.length())) + "***");
        info.put("开关状态", useDirectCall ? "开启" : "关闭");
        info.put("已使用token数", usedTokens.get());
        info.put("剩余token数", FREE_TIER_LIMIT - usedTokens.get());
        return info;
    }

    /**
     * 获取使用统计
     */
    public UsageStats getUsageStats() {
        return UsageStats.builder()
                .remainingTokens(FREE_TIER_LIMIT - usedTokens.get())
                .usagePercentage((double) usedTokens.get() / FREE_TIER_LIMIT * 100)
                .build();
    }
}